#coding=utf-8

from copy import deepcopy

from aima.search import Problem

from utils import (zero_index, interchange, Matrix)
from custom_graph_search import (custom_breadth_first_graph_search,
                                 custom_depth_first_graph_search)
from custom_ida_search import custom_iterative_deepening_search



class EightPuzzleProblem(Problem):
    
    def __init__(self, initial, goal):
        Problem.__init__(self, initial, goal)

    def successor(self, matriz):        
        zero_pos = zero_index(matriz)
        up = self.change(matriz,zero_pos,(zero_pos[0]-1,zero_pos[1]))
        down = self.change(matriz,zero_pos,(zero_pos[0]+1,zero_pos[1]))
        left = self.change(matriz,zero_pos,(zero_pos[0],zero_pos[1]-1))
        right = self.change(matriz,zero_pos,(zero_pos[0],zero_pos[1]+1))
        res = [(matriz.copy(), m) for m in [up,down,left,right] if m]
        return res

    def change(self, matriz, ipos, fpos):
        # Notar que no se cambia la matriz pasada como parámetro
        if fpos[0] in range(3) and fpos[1] in range(3):
            return interchange(matriz, ipos,fpos)
        else:
            return None

    #def path_cost(self, cost_so_far, matriz, action, B):
    #
 
    #def h(self, node):
    #   



# Here is the code that resolve this problem
if __name__ == '__main__':
    # Estado inicial del problema del ejercicio
    puzzle  = Matrix([[2,8,1],[4,6,3],[0,7,5]])
    # Objetivo
    goal    = Matrix([[1,2,3],[8,0,4],[7,6,5]])

    problem = EightPuzzleProblem(puzzle, goal)
    
    
    # TERMINA!!!
    #print "STARTING breadth first graph search"
    #final_state = custom_breadth_first_graph_search(problem)
    #print final_state
    #print "Breadth first graph search FINISHED"
    
    # NO TERMINA!!!!
    #print "STARTING depth first graph search"
    #final_state = custom_depth_first_graph_search(problem)
    #print final_state
    #print "Depth first graph search FINISHED"
    
    print "STARTING IDA search"
    final_state = custom_iterative_deepening_search(problem)
    print final_state
    print "Depth first graph search FINISHED"
